﻿using Dong.Model;
using System;
using System.IO.Ports;
using System.Windows.Forms;

namespace Stote.Forms
{
    public partial class FrmSetTemperature : BaseForm
    {
        StoreAreaBoxModel storeAreaBoxModel = null;//分区信息
        Dong.BLL.StoreArea storeAreaBLL = new Dong.BLL.StoreArea();

        public FrmSetTemperature()
        {
            InitializeComponent();
            btnStart.Click += BtnStart_Click;
            serialPort1 = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
        }

        private void FrmSetTemperature_Load(object sender, EventArgs e)
        {
            if (Tag != null)
            {
                storeAreaBoxModel = Tag as StoreAreaBoxModel;
                if (storeAreaBoxModel != null)
                {
                    lblType.Text = storeAreaBoxModel.BtnSetText;
                    nudTemperature.Value = storeAreaBoxModel.Temperature;
                    InitSetWays();
                }
            }
        }

        private void InitSetWays()
        {
            clbWayList.Items.Clear();
            if (storeAreaBoxModel.TemperatureState == 1)
            {
                clbWayList.Items.Add("打开冷风");
                clbWayList.Items.Add("关闭暖气");
                clbWayList.Items.Add("打开窗户");
            }
            if (storeAreaBoxModel.TemperatureState == 2)
            {
                clbWayList.Items.Add("打开热风");
                clbWayList.Items.Add("打开暖气");
                clbWayList.Items.Add("关闭窗户");
            }
        }

        private void BtnStart_Click(object sender, EventArgs e)
        {
            if (storeAreaBoxModel == null)
            {
                MessageBox.Show("非法进入！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            decimal temperature = nudTemperature.Value; //目标室温
            if (storeAreaBoxModel.MinTemperature > temperature)
            {
                MessageBox.Show("目标温度不能低于当前分区的最低温度！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (storeAreaBoxModel.MaxTemperature < temperature)
            {
                MessageBox.Show("目标温度不能高于当前分区的最高温度！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (clbWayList.CheckedItems.Count == 0)
            {
                MessageBox.Show("请设置调温方法！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            //开始调温处理
            try
            {
                if (!serialPort1.IsOpen) serialPort1.Open();
                decimal data = temperature * 10; // 扩大10倍
                byte highBit = (byte)(data / 256); // 获取高位
                byte lowBits = (byte)(data % 256); // 获取低位
                byte[] k = new byte[6] { 0X01, 0X06, 0X00, 0X00, highBit,lowBits }; // 准备写入温度的数据帧
                byte[] r = Crc16(k);
                byte[] buffer = new byte[8];
                Array.Copy(k, 0, buffer, 0, 6);
                Array.Copy(r, 0, buffer, 6, 2);
                serialPort1.Write(buffer, 0, buffer.Length);
                serialPort1.Close();

                // 更新数据库
                StoreArea model = storeAreaBLL.GetModel(storeAreaBoxModel.StoreAreaId);
                if (model != null)
                {
                    model.Temperature = data;
                    storeAreaBLL.Update(model);
                }

                MessageBox.Show($"手工调温成功！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                DialogResult = DialogResult.OK; // 关窗窗口
            }
            catch (Exception ex)
            {
                if (serialPort1.IsOpen) serialPort1.Close();
                MessageBox.Show($"手工调温失败！失败原因：{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private byte[] Crc16(byte[] data)
        {
            //1 初始化一个16位的寄存器地址 用作初始值
            int crc = 0xffff;
            //2 遍历数据字节
            for (int i = 0; i < data.Length; i++)
            {
                //3 将数据字节与寄存器异或
                crc = crc ^ data[i];
                //4 对寄存器进行8次迭代，每一次迭代将寄存器右移一位
                for (int j = 0; j < 8; j++)
                {
                    int temp;
                    temp = crc & 1;
                    crc = crc >> 1;//每一次迭代将寄存器右移一位
                    crc = crc & 0x7fff;
                    //5 如果最低位位1，将寄存器与生成多项式0x8005异或，否则只进行右移操作
                    if (temp == 1) crc = crc ^ 0xa001;
                    crc = crc & 0xffff;
                }
            }
            byte[] crc16 = new byte[2];// crc寄存器的高低为进行互换
            crc16[1] = (byte)((crc >> 8) & 0xff); //crc寄存器高八位变成了八低位
            crc16[0] = (byte)(crc & 0xff);// crc寄存器低八位变成了高低位
            return crc16;
        }
    }
}
